#include "StdAfx.h"
#include "from_file.h"
#include "string.h"


from_file::from_file(void)
{
}

from_file::~from_file(void)
{
}

/////////////////////////////////////////////////////////////////////////////////////
//Converts a string og 1 and 0 to its value in binary i.e. ToBinary(101) = 5
/////////////////////////////////////////////////////////////////////////////////////

int from_file::ToBinary(char* szData, int* iBitsNumber)
{
	int i =			0;
	int iResult =	0;

	*iBitsNumber = strlen(szData);
	
	while (i < *iBitsNumber)
	{
		iResult = iResult * 2 + (szData[i] - '0');
		i ++;
	}
	
	return iResult;

}


///////////////////////////////////////////////////////////////////////////////////////////
//Translates the "234.567,890,000 us" time representation as given in input file to 
//double, according to value and units
////////////////////////////////////////////////////////////////////////////////////////////  


double from_file::ParseTime(char* szTime, char* szUnits)
{
	int i =					0;
	int iNumberOfChars;
	double Degree =			0.1;
	int iBeforePoint =		1;
	double Result =			0;

	iNumberOfChars = strlen(szTime);


	while( i < iNumberOfChars )
	{
		if (szTime[i] == '.')
		{
			iBeforePoint = 0;
		}


		if (szTime[i] >= '0' && szTime[i] <= '9')
		{
			if (iBeforePoint)
			{
				Result = Result * 10 + (szTime[i] - '0');
			}
			else
			{
				Result += (szTime[i] - '0') * Degree;
				Degree /= 10;
			}
		}
		i ++;
	}

	//Negative
	if (szTime[0] == '-')
	{
		Result *= -1;
	}

	//Cycle given in us
	if (strcmp (szUnits,"us") == 0)
	{
	}
	if (strcmp (szUnits,"ns") == 0)
	{
		Result /= 1000;
	}
	if (strcmp (szUnits,"ms") == 0)
	{
		Result *= 1000;
	}
	if (strcmp (szUnits, "s") == 0)
	{
		Result *= 1000000;
	}
	//Very small
	if (strcmp (szUnits,"ps") == 0)
	{
		Result = 0;
	}

	return Result ;

}



/////////////////////////////////////////////////////////////////////////////////////////
//Counts the lines in input file, each line is a vector in vector array
// - counts number of vectors in input.
//NumOfColumns is number of signal columns (besides timestamp) in input file
//////////////////////////////////////////////////////////////////////////////////

int from_file::CountVectors(FILE* Input, int iNumOfColumns, int iInT)
{
	int i;
	int iResult = 1;
	int iNumOfVectors = 0;
	char tmp[1001];
	char szTmp[VECTOR_LENGTH];


	//Headline
	fgets(tmp,1000,Input);
	//iNumOfColumns does not include timestamp
	while (1)
	{	 
		for (i = 0; i < iNumOfColumns + 2 - iInT;  i ++)
		{
			iResult = fscanf(Input,"%s",&szTmp);	
		}
		
		if (iResult == EOF)
		{
			break;
		}	
		
		//counting rows == vectors
		iNumOfVectors ++;
	}
	//Return to beginning of file;
	fseek(Input,0,SEEK_SET);

	return iNumOfVectors;
}


////////////////////////////////////////////////////////////////////////////////////////
//Builds the VectorArray from the input file, using ParseTime, Selectbits functions.
//Fills the Absolute field in each vector, but not the Cycles
//(that will be done by UpdateCycles)
//inT indicates where the time is given in T terms, and there are no units(us, ms etc)
//to be read
////////////////////////////////////////////////////////////////////////////////////////


int from_file::ParseData(FILE* Input, int iNumOfColumns, PSVECTOR* sVectorArray, int iNumOfVectors, int iInT, int* MatchArray, int iBitsNumber)
{

	int i;
	int j;
	int iVectorIndex;
	
	char us[3];
	char tmp[1001];
//	char szData[VECTOR_LENGTH + 1];
	char* szVector;
//	int iValue;
	char szTime[32]; //max number of digits in integer

	int iResult = iNumOfColumns;
	char seps[] = " \t\n";

	
	

	//Headline
	fgets(tmp,1000,Input);


	for (iVectorIndex = 0 ; iVectorIndex < iNumOfVectors ; iVectorIndex ++)
	{
		//for += later
		(*sVectorArray)[iVectorIndex].iValue = 0;
		
		
		fgets(tmp,1000,Input);
		szVector = strtok(tmp,seps);
		for (j = 1; j < iNumOfColumns; j ++)
		{		
			strcat(szVector, strtok(NULL,seps));
		}
		
		for (i = 0; i < iBitsNumber; i++)
		{
			(*sVectorArray)[iVectorIndex].iValue += (szVector[i] - '0') << MatchArray[i];
		}

		strcpy(szTime,strtok(NULL,seps));
		if (iInT == OFF)
		{
			strcpy(us,strtok(NULL,seps));
		}
		
		
		(*sVectorArray)[iVectorIndex].Absolute = ParseTime(szTime, us);
		//DEBUG
		/*
		printf	(" input : %d \t\t %d\n",
				(*sVectorArray)[iVectorIndex].iValue,
				(*sVectorArray)[iVectorIndex].iCycles);
*/
	}
	return iNumOfVectors;
}


/////////////////////////////////////////////////////////////////////////////////
//Counts number of different vectors in WithRepeatsVectorArray
//Note that it counts the zero dummy vector in it too
//////////////////////////////////////////////////////////////////

int from_file::CountNoRepeats(PSVECTOR sWithRepeatsVectorArray, int iNumberOfVectors)
{
	int iCounter = 0;
	int i;
	
	for (i = 0; i <  iNumberOfVectors - 1; i++)
	{
		if (sWithRepeatsVectorArray[i].iValue == sWithRepeatsVectorArray[i + 1].iValue)
		{
			continue;
		}
		iCounter ++;

	}
	return iCounter;

}




/////////////////////////////////////////////////////////////////////////
//Creates a valid (with no repeats, where each vector is different from its
//predecessor) SlowVectorArray from WithRepeatsVectorArray. 
//Returns number of vectors in SlowVectorArray.
//////////////////////////////////////////////////////////////////////////
  
int from_file::LeaveNoRepeats(PSVECTOR sWithRepeatsVectorArray, int iVectorsInWithRepeats, PSVECTOR* sSlowVectorArray)
{
	int i;
	int iNew = 0;
	int iRepeatSeq = 0;

	for  (i = 0; i < iVectorsInWithRepeats - 1; i++)
	{
		if ( !iRepeatSeq )
		{
			mblock.CopyVector((*sSlowVectorArray)+iNew, sWithRepeatsVectorArray+i);
			iNew ++;
		}
		
		if (sWithRepeatsVectorArray[i].iValue == sWithRepeatsVectorArray[i + 1].iValue)
		{
			iRepeatSeq = 1;
		}
		else
		{
			iRepeatSeq = 0;
		}
	}
	//Copy last vector
	mblock.CopyVector((*sSlowVectorArray)+iNew, sWithRepeatsVectorArray + iVectorsInWithRepeats - 1);
	iNew ++;
	
	return iNew;
}




///////////////////////////////////////////////////////////////////////////////////
//Creates a valid (where between each 2 vectors there is atleast Threshhold us difference
//(in Absolute time)) Vector Array  - in Destination, from Source.
//Returns number of vectors in Destination
////////////////////////////////////////////////////////////////////////////////////

int from_file::RemoveZeros(PSVECTOR sSource, int iVectorsInSource, PSVECTOR* sDestination, double Threshhold)
{
	int i;
	int j;
	for (i = 0, j = 0; i < iVectorsInSource - 1; i ++)
	
	{
		if (sSource[i+1].Absolute - sSource[i].Absolute > Threshhold)
		{
			mblock.CopyVector((*sDestination) + j,sSource + i);
			j++;
		}
	}
	//Last Vector is used for reference
	mblock.CopyVector((*sDestination) + j,sSource + i);
	j ++;
	return j;
}



double from_file::FindPhase(PSLINE sLineArray, int iNumOfLines, int iSignal, double ClockCycle)
{
	int i;
	int j;
	int iNumOfVectors;
	int counter = 0;
	int iMask;
	int intDif;
	double phase = 0;
		
	
	iMask= 1 << iSignal;

	for (i = 0; i < iNumOfLines; i ++)
	{
		iNumOfVectors = sLineArray[i].sLast - sLineArray[i].sFirst + 1;
		for (j = 0; j < iNumOfVectors - 1; j ++)
			if ( ((sLineArray[i].sFirst + j)->iValue & iMask) != 
				 ((sLineArray[i].sFirst + j + 1)->iValue & iMask) )
			{
				intDif = mblock.Round(((sLineArray[i].sFirst + j + 1)->Absolute - 
								sLineArray[i].sFirst->Absolute)/ClockCycle, CLOSEST);
				phase += ((sLineArray[i].sFirst + j+ 1)->Absolute - 
							sLineArray[i].sFirst->Absolute - intDif * ClockCycle);
				counter ++;
			}
	}
	if (counter != 0)
	{
		phase /= counter;
	}
	return phase;
}




double from_file::UpdatePhases(PSLINE sLineArray, int iNumOfLines, int iRefSignal, double ClockCycle, PSUTG_SIGNAL sSignals)
{
//	int i;
//	int iMask;
//	double RefTime;
//	int iRefIndex;
	int iSignal;
/*	
	iMask = 1 << iRefSignal;
	for (i = 0; i < iNumOfVectors - 1; i ++)
	{
		if ( (sVectorArray[i].iValue & iMask) != 
			 (sVectorArray[i + 1].iValue & iMask) )
		{
			iRefIndex = i + 1;
			RefTime = sVectorArray[i + 1].Absolute;
			break;
		}

	}
*/
	for (iSignal = V1; iSignal < VECTOR_LENGTH; iSignal ++)
	{
		if ( (iSignal == iRefSignal) || (iSignal == RESERVED) )
		{
			continue;
		}
		sSignals[iSignal].Phase = FindPhase(sLineArray,
											iNumOfLines, 
											iSignal, 
											//RefTime, 
											//iRefIndex, 
											ClockCycle);
	}
	return 1;//RefTime;
}


